/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package pe.edu.pucp.dp1.persistencia.bd;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

/**
 *
 * @author javier
 */
public class InstaladorBaseDatos extends javax.swing.JFrame {

    File[] archivos;
    private Registry registry;

    public class Analizador extends Thread {

        int indexArchI;
        int indexArchF;

        public Analizador(int indexArchivoInicial, int indexArchivoFinal) {
            super();
            indexArchF = indexArchivoFinal;
            indexArchI = indexArchivoInicial;
        }

        public void run() {
            //System.out.println("Analiza archivo de " + indexArchI + " a " + indexArchF);
            for (int i = indexArchI; i < indexArchF; i++) {
                String nombreArchivo = archivos[i].getAbsolutePath();
                if (nombreArchivo.contains("gps")) {
                    AnalizarArchivo(archivos[i].getAbsolutePath());
                }
            }
        }
    }

    Properties misPropiedades;
    public int ANCHO;
    public int LARGO;
    int tamanioFila;
    int tamanioColumna;
    int distanciaEntreAvenidas;
    int diasXSemana;
    int cantHorasAlDia;
    int velocidad_default;
    String velocidad_horizontal_multiplos;
    String velocidad_vertical_multiplos;
    int distanciaEntreSemaforos_default;
    //JAVIER : atributos derivados
    int numColumnas;
    int numFilas;
    int numeroZonas;
    int[] cantAutosxHora;
    int[] zonas;
    int[][] patrones;
    String[][] tabla;
    String[][] historico; //es la representacion en String de patrones para copiar a BD
    int numColumnasEnMapa;
    //JAVIER: otros;
    String pathScriptTablaPatron;
    //String pathVehiculos;
    //String pathIntersecciones;
    //String pathDatosIntervalos;
    String pathScriptTablaHistorico;
    String pathScriptLimitesVelocidad;
    String pathScriptIntersecciones;
    //Javier: conexion a base de datos;
    String JDBC_DRIVER;
    String DB_URL;
    String USER;
    String PASS;
    //JAvier: otros mas
    ArrayList multiplicidadHorizontal = new ArrayList();
    ArrayList multiplicidadVertical = new ArrayList();
    String mensajeError = "";
    int cantHilos = 10;

    /**
     * Creates new form InstaladorBaseDatos
     */
    public InstaladorBaseDatos() {
        initComponents();
        jTextArea1.setEditable(false);
        HabilitarCargaDeServicio(false);

    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel4 = new javax.swing.JLabel();
        jTextField4 = new javax.swing.JTextField();
        jButton1 = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        jButton3 = new javax.swing.JButton();
        jLabel6 = new javax.swing.JLabel();
        jButton2 = new javax.swing.JButton();
        jButton4 = new javax.swing.JButton();
        jTextField5 = new javax.swing.JTextField();
        jLabel7 = new javax.swing.JLabel();
        jTextField6 = new javax.swing.JTextField();
        jButton5 = new javax.swing.JButton();
        jCheckBox1 = new javax.swing.JCheckBox();
        jLabel8 = new javax.swing.JLabel();
        jButton6 = new javax.swing.JButton();
        jLabel9 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Configuración del Servidor de Persistencia");
        setResizable(false);

        jLabel4.setText("Path de Arch. históricos");

        jButton1.setText("Examinar");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jTextArea1.setColumns(20);
        jTextArea1.setRows(5);
        jScrollPane1.setViewportView(jTextArea1);

        jButton3.setText("Iniciar Reconocimiento de Patrones");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                IniciarReconocimientoDePatrones(evt);
            }
        });

        jLabel6.setFont(new java.awt.Font("Ubuntu", 1, 16)); // NOI18N
        jLabel6.setText("Complete el formulario :");

        jButton2.setText("Cerrar");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                Cerrar(evt);
            }
        });

        jButton4.setText("Iniciar Servicio Persistencia");
        jButton4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                IniciarServicioPersistencia(evt);
            }
        });

        jTextField5.setText("wlan0");
        jTextField5.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextField5ActionPerformed(evt);
            }
        });
        jTextField5.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                jTextField5FocusLost(evt);
            }
        });

        jLabel7.setText("Path de scripts");

        jButton5.setText("Examinar");
        jButton5.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton5ActionPerformed(evt);
            }
        });

        jCheckBox1.setText("Publicar servicio");
        jCheckBox1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox1ActionPerformed(evt);
            }
        });

        jLabel8.setText("Interfaz");

        jButton6.setText("Cargar Scripts a BD");
        jButton6.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton6ActionPerformed(evt);
            }
        });

        jLabel9.setText("IP: ");

        jLabel10.setText("0.0.0.0");

        jLabel11.setText("ej: eth0,wlan0");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLabel4)
                                    .addComponent(jLabel7))
                                .addGap(18, 18, 18))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jCheckBox1)
                                .addGap(43, 43, 43)))
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(35, 35, 35)
                                .addComponent(jLabel8)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jTextField5, javax.swing.GroupLayout.PREFERRED_SIZE, 61, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jLabel11)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(jLabel9))
                            .addComponent(jTextField6)
                            .addComponent(jTextField4, javax.swing.GroupLayout.Alignment.TRAILING))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 157, Short.MAX_VALUE)
                            .addComponent(jButton5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, 139, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel6)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jButton3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton6, javax.swing.GroupLayout.DEFAULT_SIZE, 221, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton4, javax.swing.GroupLayout.PREFERRED_SIZE, 205, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton2)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel6)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(jTextField4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButton1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jTextField6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel7)
                        .addComponent(jButton5)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jCheckBox1)
                    .addComponent(jLabel8)
                    .addComponent(jTextField5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel9)
                    .addComponent(jLabel10)
                    .addComponent(jLabel11))
                .addGap(7, 7, 7)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 253, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton3)
                    .addComponent(jButton2)
                    .addComponent(jButton4)
                    .addComponent(jButton6))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        jTextField4.setText(abrirRuta(JFileChooser.DIRECTORIES_ONLY));
    }//GEN-LAST:event_jButton1ActionPerformed

    private void IniciarReconocimientoDePatrones(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_IniciarReconocimientoDePatrones
        //////////////////////////////////////////////////////////////
        CargarConfiguracionDeVariablesIniciales();
        //Javier: SE INICIA TODO EL PROCESO DE CARGA DE DATOS A LA BD
        if (CondicionesReconocimientoPatrones()) {
            if (AnalizarArchivos2()) {
                Mensaje("Finalizado.\n");
                Mensaje("Preparando estadísticas...");
                PrepararEstadisticas();
                Mensaje("Finalizado.\n");
                //===================SE GENERAN SCRIPTS=============================
                Mensaje("Generando scripts...");
                GenerarScriptPatrones(pathScriptTablaPatron, "patron");
                GenerarScriptHistoricos(pathScriptTablaHistorico, "historico");
                GenerarScriptIntersecciones(pathScriptIntersecciones, "interseccion");
                GenerarScriptVelocidadesAvenidas(pathScriptLimitesVelocidad, "limites");
                Mensaje("Finalizado.\n");
                JOptionPane.showMessageDialog(this, "El reconocimiento de patrones ha finalizado sin errores.");

            } else {
                jTextArea1.append(mensajeError);
                jTextArea1.update(jTextArea1.getGraphics());
            }
        }

    }//GEN-LAST:event_IniciarReconocimientoDePatrones

    private void Cerrar(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_Cerrar
        // TODO add your handling code here:
        System.exit(WIDTH);
    }//GEN-LAST:event_Cerrar

    private void IniciarServicioPersistencia(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_IniciarServicioPersistencia
        // TODO add your handling code here:
        try {
            String cmd = "rmiregistry"; //Comando de apagado en linux
            Runtime.getRuntime().exec(cmd);
            // cmd = "java -cp mysql-connector-java-5.1.18-bin.jar:. -Djava.security.policy=politicaSeguridad -Djava.rmi.server.hostname=192.168.0.35 ServidorDePersistencia"; //Comando de apagado en linux
            String ip= jLabel10.getText();
            try {
                //registry = LocateRegistry.createRegistry(1099);
                //registry = LocateRegistry.getRegistry(ip,1099); 
                //Naming.rebind("//192.168.1.201:1099/BaseDatos", new BaseDatos()); //en mi casa
                System.setProperty("java.rmi.server.codebase","http://ip/");
                Naming.rebind("//"+ip+":1099/BaseDatos", new BaseDatos()); //con mi celular
                //Naming.rebind("//192.168.0.35:1099/BaseDatos", new BaseDatos()); //en la casa de choque
                //Naming.rebind("//192.168.1.200:1099/BaseDatos", new BaseDatos()); // via cablecito
                System.out.println("Servidor Persistencia listo...");
//            System.out.println(RemoteServer.getClientHost());
            } catch (Exception e) {
                System.out.println("Servidor fallo... " + e);
            }

        } catch (IOException ioe) {
            System.out.println(ioe);
        }
        //ServidorDePersistencia.main(null);
    }//GEN-LAST:event_IniciarServicioPersistencia

    private void jTextField5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField5ActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_jTextField5ActionPerformed

    private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton5ActionPerformed
        // TODO add your handling code here:
        jTextField6.setText(abrirRuta(JFileChooser.DIRECTORIES_ONLY));
    }//GEN-LAST:event_jButton5ActionPerformed

    private void jCheckBox1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox1ActionPerformed
        // TODO add your handling code here:
        if (jCheckBox1.isSelected()) {
            HabilitarCargaDeServicio(true);

        } else {
            HabilitarCargaDeServicio(false);
        }
    }//GEN-LAST:event_jCheckBox1ActionPerformed

    private void jButton6ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton6ActionPerformed
        // TODO add your handling code here:
        CargarConfiguracionDeVariablesIniciales();
        if (CondicionesCargaDeDatos()) {
            //================SE CARGAN SCRIPTS A BD===========================
            Mensaje("Cargando tabla de patrones a BD...");
            CargarScriptABaseDatos(pathScriptTablaPatron);
            Mensaje("Finalizado.\n");
            Mensaje("Cargando tabla historica a BD...");
            CargarScriptABaseDatos(pathScriptTablaHistorico);
            Mensaje("Finalizado.\n");
            Mensaje("Cargando velocidades limites...");
            CargarScriptABaseDatos(pathScriptLimitesVelocidad);
            Mensaje("Finalizado.\n");
            Mensaje("Cargando posiciones de intersecciones semaforizadas...");
            CargarScriptABaseDatos(pathScriptIntersecciones);
            Mensaje("Finalizado.\n");

            JOptionPane.showMessageDialog(this, "La carga de información a BD ha finalizado sin errores.");
            jTextField4.setEnabled(false);
            jTextArea1.setEditable(false);
            jTextArea1.setEnabled(false);
            jButton1.setEnabled(false);
            jButton3.setEnabled(false);
        }
    }//GEN-LAST:event_jButton6ActionPerformed

    private void jTextField5FocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jTextField5FocusLost
        // TODO add your handling code here:
        InetAddress ip = GetLocalIP(jTextField5.getText());
        if (ip != null) {
            jLabel10.setText(ip.getHostAddress());
        } else {
            jLabel10.setText("0.0.0.0");
        }
    }//GEN-LAST:event_jTextField5FocusLost

    private String abrirRuta(int x) {
        JFileChooser file = new JFileChooser();
        file.setFileSelectionMode(x);
        file.showOpenDialog(this);
        return file.getSelectedFile().getAbsolutePath();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(InstaladorBaseDatos.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(InstaladorBaseDatos.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(InstaladorBaseDatos.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(InstaladorBaseDatos.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new InstaladorBaseDatos().setVisible(true);
            }
        });
    }

    //JAVIER = PROCESOS INTERNOS================================================
    private int QueDiaEsFecha(int dia, int mes, int anio) {
        int rpta = 0;
        int semana = 0;
        int x, j, z, año1, y, u, total;
        if ((anio / 100) % 4 == 1) {
            x = semana + 5;
        } else if ((anio / 100) % 4 == 2) {
            x = semana + 3;
        } else if ((anio / 100) % 4 == 3) {
            x = semana + 1;
        } else if ((anio / 100) % 4 == 0) {
            x = semana + 0;
        } else {
            x = 0;
        }
        j = 0;
        z = 0;
        año1 = (anio % 100) + ((anio % 100) / 4);
        y = 0;
        if (anio % 400 == 0 && anio % 100 != 0 && anio % 4 == 0) {
            if (mes == 1 || mes == 2) {
                j = z - 1;
            } else {
                j = z + 0;
            }
        }
        if (mes == 8) {
            u = y + 1;
        } else if (mes == 2 || mes == 3 || mes == 11) {
            u = y + 2;
        } else if (mes == 6) {
            u = y + 3;
        } else if (mes == 9 || mes == 12) {
            u = y + 4;
        } else if (mes == 4 || mes == 7) {
            u = y + 5;
        } else if (mes == 1 || mes == 10) {
            u = y + 6;
        } else {
            u = y + 0;
        }
        total = x + y + z + año1 + u + dia + j;
        if (total % 7 == 1) {
            return 1;//System.out.print("Lunes");
        } else if (total % 7 == 2) {
            return 2;//System.out.print("Martes");
        } else if (total % 7 == 3) {
            return 3;//System.out.print("Miercoles");
        } else if (total % 7 == 4) {
            return 4;//System.out.print("Jueves");
        } else if (total % 7 == 5) {
            return 5;//System.out.print("Viernes");
        } else if (total % 7 == 6) {
            return 6;//System.out.print("Sabado");
        } else {
            return 7;//System.out.print("Domingo");
        }
    }

    private void limpiarArreglos() {
        for (int i = 0; i < cantHorasAlDia; i++) {
            cantAutosxHora[i] = 0;
        }
        for (int i = 0; i < numeroZonas; i++) {
            zonas[i] = 0;
        }
    }

    private int ObtenerZonaNuevaVersion(String linea) {
        String[] result = linea.split(",");
        String sx = result[1];
        String sy = result[2];
        int x = Integer.parseInt(sx);
        int y = Integer.parseInt(sy);
        double fila = 0;
        double columna = 0;
//        fila = Math.ceil((double) y / (double) tamanioFila) - 1;
//        columna = Math.ceil((double) x / (double) tamanioColumna) - 1;
//        fila = Math.ceil((double) x / (double) tamanioFila) - 1;
//        columna = Math.ceil((double) y / (double) tamanioColumna) - 1;
        fila = (int) (Math.ceil((double) y / (double) tamanioFila) - 1) > 0 ? (int) (Math.ceil((double) y / (double) tamanioFila) - 1) : 0;
        columna = (int) (Math.ceil((double) x / (double) tamanioFila) - 1) > 0 ? (int) (Math.ceil((double) x / (double) tamanioColumna) - 1) : 0;
        double zona = numColumnasEnMapa * fila + columna;

        return (int) zona;// - 1;
    }

    private int ObtenerHoraNuevaVersion(String linea) {
        //String[] result = linea.split("\\s");
        //String HoraTotal = result[5];
        String[] result2 = linea.split(":");
        int hora = Integer.parseInt(result2[0]);
        //
        return hora;
    }

    private int ObtenerDiaNuevaVersion(String path) {
        //
        String[] result = path.split("\\.");
        //String haber = result[6];
        String pedacito = result[2].substring(0, 4);
        int year = Integer.parseInt(pedacito);
        pedacito = result[2].substring(4, 6);
        int month = Integer.parseInt(pedacito);
        pedacito = result[2].substring(6, 8);
        int day = Integer.parseInt(pedacito);
        int d = QueDiaEsFecha(day, month, year);
        return d;
    }

    private boolean AnalizarArchivo(String ruta) {

        File archivo = new File(ruta);
        FileReader entrada;
        int zonaAnterior = -1;
        int nuevaZona = 0;
        String linea = "";
        try {
            entrada = new FileReader(archivo);
            BufferedReader lector = new BufferedReader(entrada);
            linea = lector.readLine();
            int horaAnterior = -1;
            int nuevaHora = 0;

            int diaAnterior = -1;
            int nuevoDia = 0;
            int contador = 1;
            boolean huboAlteracion = false;
            while (linea != null) {
                //===============================================
                //nuevoDia = ObtenerDia(linea);
                nuevoDia = ObtenerDiaNuevaVersion(ruta);
                if (nuevoDia != diaAnterior) {
                    huboAlteracion = true;
                    //zonas[nuevaZona] = zonas[nuevaZona] + 1;
                    diaAnterior = nuevoDia;
                }
                //===============================================
                //nuevaHora = ObtenerHora(linea);
                nuevaHora = ObtenerHoraNuevaVersion(linea);
                if (nuevaHora != horaAnterior) {
                    huboAlteracion = true;
                    //cantAutosxHora[nuevaHora] = cantAutosxHora[nuevaHora] + 1;
                    horaAnterior = nuevaHora;
                }
                //===============================================
                //nuevaZona = ObtenerZona(linea);
                nuevaZona = ObtenerZonaNuevaVersion(linea);
                //if (nuevaZona<38400 && nuevaZona>=0)
                if (nuevaZona != zonaAnterior) {
                    huboAlteracion = true;
                    //zonas[nuevaZona] = zonas[nuevaZona] + 1;
                    zonaAnterior = nuevaZona;
                }

                //===============================================
                if (huboAlteracion) {
                    int columna = cantHorasAlDia * (nuevoDia - 1) + nuevaHora;
                    patrones[nuevaZona][columna] = patrones[nuevaZona][columna] + 1;
                    huboAlteracion = false;
                }
                //===============================================
                linea = lector.readLine();
                //contador++;
            }
            return true;
        } catch (FileNotFoundException ex) {
            //Logger.getLogger(Generador.class.getName()).log(Level.SEVERE, null, ex);
            Mensaje("Error (FNF) al procesar archivo :" + ruta + "\n");
            return false;
        } catch (IOException ex) {
            //Logger.getLogger(Generador.class.getName()).log(Level.SEVERE, null, ex);
            Mensaje("Error (I/O) al procesar archivo :" + ruta + "\n");
            return false;
        } catch (Exception ex) {
            Mensaje("(Zona = " + nuevaZona + "): Error al procesar archivo :" + ruta + "\n");
            Mensaje(linea + "\n");
            return false;
        }
    }

    private boolean AnalizarArchivos2() {
        limpiarArreglos();

        if (jTextField4.getText().length() > 0) {
            String ruta = jTextField4.getText();
            File directorio = new File(ruta);
            if (directorio.isDirectory()) {
                archivos = directorio.listFiles();
                int cantidadArchivos = archivos.length;
                Mensaje("Analizando archivos...\n");
                int tamGrupo = (int) (cantidadArchivos / cantHilos);
                System.out.println("Cantidad de archivo = " + cantidadArchivos);
                System.out.println("tamGrupo = " + tamGrupo);
                Analizador hilofinal = null;
                for (int j = 0; j < cantHilos; j++) {
                    if (j == cantHilos - 1) {
                        hilofinal = new Analizador(j * tamGrupo, cantidadArchivos);
                        hilofinal.start();
                    } else {
                        Analizador hilo = new Analizador(j * tamGrupo, (j * tamGrupo) + tamGrupo - 1);
                        hilo.start();
                    }
                }
                try {
                    hilofinal.join(); //espera al ultimo hilo
                } catch (InterruptedException ex) {
                    Logger.getLogger(InstaladorBaseDatos.class.getName()).log(Level.SEVERE, null, ex);
                }
                return true;
            } else {
                mensajeError = "Revise la ruta de archivo proporcionada\n";
                return false;
            }
        } else {
            mensajeError = "Ingrese una ruta de ubicación de datos histórica\n";
            return false;
        }
    }

    private void PrepararEstadisticas() {
        for (int i = 0; i < numeroZonas; i++) {

            for (int j = 0; j < diasXSemana; j++) {
                int inicioColumna = (j) * (cantHorasAlDia);
                int sumatoria = 0;
                String cad = "";
                for (int k = inicioColumna; k < inicioColumna + cantHorasAlDia; k++) {
                    sumatoria += patrones[i][k];
                    cad = cad + patrones[i][k] + ",";
                }
                historico[i][j] = cad;
                double promedioDiario = sumatoria / diasXSemana;
                String cadena = "";
                for (int k = inicioColumna; k < inicioColumna + cantHorasAlDia; k++) {
                    if (patrones[i][k] <= promedioDiario) {
                        cadena = cadena + "0";
                    } else {
                        cadena = cadena + "1";
                    }
                }
                tabla[i][j] = cadena;
            }

        }
    }

    private void GenerarScriptPatrones(String nombreArchivo, String nombreTabla) {
        File archivo = new File(nombreArchivo);
        try {
            FileWriter algo = new FileWriter(archivo);
            PrintWriter buffer = new PrintWriter(algo);
            buffer.println(creaTablaUsuario);
            buffer.println(creaTablaPatron);
            buffer.println("DELETE FROM " + nombreTabla + " WHERE zona>=0;");
            for (int i = 0; i < numeroZonas; i++) {
                buffer.println("INSERT INTO " + nombreTabla + " VALUES (" + i + ",'" + tabla[i][0] + "','"
                        + tabla[i][1] + "','" + tabla[i][2] + "','" + tabla[i][3] + "','" + tabla[i][4]
                        + "','" + tabla[i][5] + "','" + tabla[i][6] + "');");
            }
            buffer.close();
            algo.close();
        } catch (IOException ex) {
            //Logger.getLogger(Analizador.class.getName()).log(Level.SEVERE, null, ex);

        }

    }

    private void GenerarScriptHistoricos(String nombreArchivo, String nombreTabla) {
        File archivo = new File(nombreArchivo);
        try {
            FileWriter algo = new FileWriter(archivo);
            PrintWriter buffer = new PrintWriter(algo);
            buffer.println(creaTablaHistorico);
            buffer.println("DELETE FROM " + nombreTabla + " WHERE zona>=0;");
            for (int i = 0; i < numeroZonas; i++) {
                buffer.println("INSERT INTO " + nombreTabla + " VALUES (" + i + ",'" + historico[i][0] + "','"
                        + historico[i][1] + "','" + historico[i][2] + "','" + historico[i][3] + "','" + historico[i][4]
                        + "','" + historico[i][5] + "','" + historico[i][6] + "');");
            }
            buffer.close();
            algo.close();
        } catch (IOException ex) {
            //Logger.getLogger(Analizador.class.getName()).log(Level.SEVERE, null, ex);

        }

    }

    public void GenerarScriptVelocidadesAvenidas(String nombreArchivo, String nombreTabla) {
        File archivo = new File(nombreArchivo);
        int velocidadDefault = velocidad_default;
        try {
            cargarVelocidadesHorizontalesMultiplicidad(velocidad_horizontal_multiplos);
            cargarVelocidadesVerticalesMultiplicidad(velocidad_vertical_multiplos);
            FileWriter algo = new FileWriter(archivo);
            PrintWriter buffer = new PrintWriter(algo);
            buffer.println(creaTablaLimites);
            buffer.println("DELETE FROM " + nombreTabla + " WHERE avenida>=0;");
            for (int i = 0; i < LARGO; i = i + distanciaEntreAvenidas) {

                boolean tieneMultiplicidad = false;
                for (int j = 0; j < multiplicidadHorizontal.size(); j = j + 2) {
                    int x = (int) multiplicidadHorizontal.get(j);
                    if (i % x == 0) {
                        buffer.println("INSERT INTO " + nombreTabla + " VALUES (" + i + ","
                                + "'H'," + multiplicidadHorizontal.get(j + 1) + ");");
                        tieneMultiplicidad = true;
                        break;
                    }
                }
                if (!tieneMultiplicidad) {
                    buffer.println("INSERT INTO " + nombreTabla + " VALUES (" + i + ","
                            + "'H'," + velocidadDefault + ");");
                }
            }
            for (int i = 0; i < ANCHO; i = i + distanciaEntreAvenidas) {

                boolean tieneMultiplicidad = false;
                for (int j = 0; j < multiplicidadVertical.size(); j = j + 2) {
                    int x = (int) multiplicidadVertical.get(j);
                    if (i % x == 0) {
                        buffer.println("INSERT INTO " + nombreTabla + " VALUES (" + i + ","
                                + "'V'," + multiplicidadVertical.get(j + 1) + ");");
                        tieneMultiplicidad = true;
                        break;
                    }
                }
                if (!tieneMultiplicidad) {
                    buffer.println("INSERT INTO " + nombreTabla + " VALUES (" + i + ","
                            + "'V'," + velocidadDefault + ");");
                }
            }
            buffer.close();
            algo.close();
        } catch (/*IO*/Exception ex) {
            //Logger.getLogger(Analizador.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private void GenerarScriptIntersecciones(String nombreArchivo, String nombreTabla) {
        try {
            //
            BaseDatos bd = new BaseDatos();
            File archivo = new File(nombreArchivo);
            int distanciaEntreSemaforos_default = this.distanciaEntreSemaforos_default;
            try {
                //cargarVelocidadesHorizontalesMultiplicidad(velocidad_horizontal_multiplos);
                //cargarVelocidadesVerticalesMultiplicidad(velocidad_vertical_multiplos);
                FileWriter algo = new FileWriter(archivo);
                PrintWriter buffer = new PrintWriter(algo);
                buffer.println(creaTablaInterseccion);
                buffer.println("DELETE FROM " + nombreTabla + " WHERE zona>=0;");
                for (int i = 0; i < LARGO; i = i + distanciaEntreSemaforos_default) {
                    for (int j = 0; j < ANCHO; j = j + distanciaEntreSemaforos_default) {
                        if ((i % distanciaEntreSemaforos_default == 0)
                                || (j % distanciaEntreSemaforos_default == 0)) {
                            int zona = bd.ZonaDeCoordenadas(i, j);
                            buffer.println("INSERT INTO " + nombreTabla + " VALUES (" + zona + ","
                                    + j + "," + i + ");");
                        }
                    }
                }
                buffer.close();
                algo.close();
            } catch (/*IO*/Exception ex) {
                //Logger.getLogger(Analizador.class.getName()).log(Level.SEVERE, null, ex);
            }

        } catch (/*IO*/RemoteException ex) {
            Logger.getLogger(InstaladorBaseDatos.class.getName()).log(Level.SEVERE, null, ex);
            //Logger.getLogger(Analizador.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private void cargarVelocidadesHorizontalesMultiplicidad(String cadenaCompleta) {
        String cadena = cadenaCompleta;
        String[] partes = cadena.split(",");
        for (int i = 0; i < partes.length; i++) {
            int n = Integer.parseInt(partes[i]);
            multiplicidadHorizontal.add(n);
        }
    }

    private void cargarVelocidadesVerticalesMultiplicidad(String cadenaCompleta) {
        String cadena = cadenaCompleta;
        String[] partes = cadena.split(",");
        for (int i = 0; i < partes.length; i++) {
            int n = Integer.parseInt(partes[i]);
            multiplicidadVertical.add(n);
        }
    }

    //GUARDARENBASEDEDATOS===========================================================
    public void CargarScriptABaseDatos(String nombreArchivo) {
        String aSQLScriptFilePath = nombreArchivo;

        // Create MySql Connection
        //Class.forName("com.mysql.jdbc.Driver");
        Connection con;
        try {
            con = DriverManager.getConnection(DB_URL, USER, PASS);
            Statement stmt = null;
            try {
                // Initialize object for ScripRunner
                ScriptRunner sr = new ScriptRunner(con, false, false);
                Statement st = (Statement) con.createStatement();
                // Give the input file to Reader
                Reader reader = new BufferedReader(
                        new FileReader(aSQLScriptFilePath));

                // Exctute script
                sr.runScript(reader);
                con.close();

            } catch (Exception e) {
                System.err.println("Failed to Execute" + aSQLScriptFilePath
                        + " The error is " + e.getMessage());
            }
        } catch (SQLException ex) {
            System.out.println("Exception :" + ex);
        }

    }
    //==========================================================================

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JButton jButton5;
    private javax.swing.JButton jButton6;
    private javax.swing.JCheckBox jCheckBox1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JTextField jTextField4;
    private javax.swing.JTextField jTextField5;
    private javax.swing.JTextField jTextField6;
    // End of variables declaration//GEN-END:variables

    private void CargarConfiguracionDeVariablesIniciales() {
        this.misPropiedades = new MisPropiedades().getProperties();
        this.ANCHO = Integer.parseInt(this.misPropiedades.getProperty("ANCHO"));
        this.LARGO = Integer.parseInt(this.misPropiedades.getProperty("LARGO"));
        this.tamanioFila = Integer.parseInt(this.misPropiedades.getProperty("tamanioFila"));
        this.tamanioColumna = Integer.parseInt(this.misPropiedades.getProperty("tamanioColumna"));
        this.velocidad_default = Integer.parseInt(this.misPropiedades.getProperty("velocidad_default"));
        this.velocidad_horizontal_multiplos = this.misPropiedades.getProperty("velocidad_horizontal_multiplos");
        this.velocidad_vertical_multiplos = this.misPropiedades.getProperty("velocidad_vertical_multiplos");
        this.distanciaEntreAvenidas = Integer.parseInt(this.misPropiedades.getProperty("distanciaEntreAvenidas"));
        this.diasXSemana = Integer.parseInt(this.misPropiedades.getProperty("diasXSemana"));
        this.cantHorasAlDia = Integer.parseInt(this.misPropiedades.getProperty("cantHorasAlDia"));
        this.distanciaEntreSemaforos_default = Integer.parseInt(this.misPropiedades.getProperty("distanciaEntreSemaforos_default"));

        //JAVIER: campos derivados de los atributos anteriores;
        numColumnas = ANCHO / tamanioColumna; //240
        numFilas = LARGO / tamanioFila; //160
        numeroZonas = numColumnas * numFilas; //240 * 160;
        cantAutosxHora = new int[cantHorasAlDia];
        zonas = new int[numeroZonas];
        patrones = new int[numeroZonas][diasXSemana * cantHorasAlDia];
        tabla = new String[numeroZonas][diasXSemana];
        historico = new String[numeroZonas][diasXSemana];
        numColumnasEnMapa = ANCHO / tamanioColumna;

        //JAVIER: otros campos
        pathScriptTablaPatron = this.misPropiedades.getProperty("pathScriptTablaPatron");
        pathScriptTablaHistorico = this.misPropiedades.getProperty("pathScriptTablaHistorico");
        pathScriptLimitesVelocidad = this.misPropiedades.getProperty("pathScriptLimitesVelocidad");
        pathScriptIntersecciones = this.misPropiedades.getProperty("pathScriptIntersecciones");

        //JAVIER : conexion a base de datos;
        JDBC_DRIVER = this.misPropiedades.getProperty("JDBC_DRIVER");
        DB_URL = this.misPropiedades.getProperty("DB_URL");
        USER = this.misPropiedades.getProperty("USER");
        PASS = this.misPropiedades.getProperty("PASS");

        //JAVIER : nueva asignación
        String ruta = jTextField6.getText();
        pathScriptTablaPatron = ruta + "/scriptpatron.sql";
        pathScriptTablaHistorico = ruta + "/scripthistorico.sql";
        pathScriptLimitesVelocidad = ruta + "/scriptlimitesvelocidad.sql";
        pathScriptIntersecciones = ruta + "/scriptintersecciones.sql";
    }

    // Javier: Cambiar con el nombre de la interfaz
    private InetAddress GetLocalIP(String nombreInterfaz) {
        InetAddress rpta;
        try {

            NetworkInterface i = NetworkInterface.getByName(nombreInterfaz);
            if (i != null) {
                Enumeration<InetAddress> iplist = i.getInetAddresses();

                InetAddress addr = null;

                while (iplist.hasMoreElements()) {
                    InetAddress ad = iplist.nextElement();
                    byte bs[] = ad.getAddress();
                    if (bs.length == 4 && bs[0] != 127) {
                        addr = ad;
// You could also display the host name here, to 
// see the whole list, and remove the break.
                        //break;
                    }
                }

                if (addr != null) {
                    rpta = addr;
                    return rpta;
                }
            }
        } catch (SocketException ex) {
            Logger.getLogger(InstaladorBaseDatos.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;

    }

    private void HabilitarCargaDeServicio(boolean b) {
        jButton4.setEnabled(b);
        jTextField5.setEnabled(b);

    }

    private boolean CondicionesReconocimientoPatrones() {
        if (jTextField4.getText().length() > 0 && jTextField6.getText().length() > 0) {
            return true;
        } else {
            Mensaje("Seleccione una ruta para archivos históricos y para "
                    + "guardar los scripts de reconocimiento de patrones\n");
            return false;
        }
    }

    private void Mensaje(String mensaje) {
        jTextArea1.append(mensaje);
        jTextArea1.update(jTextArea1.getGraphics());
    }

    private boolean CondicionesCargaDeDatos() {
        if (jTextField6.getText().length() > 0) {
            return true;
        } else {
            Mensaje("Seleccione una ruta para los scripts de reconocimiento de patrones\n");
            return false;
        }
    }

    String creaTablaHistorico = "DROP TABLE IF EXISTS `historico`;\n"
            + "CREATE TABLE `historico` (\n"
            + "  `zona` int(11) NOT NULL,\n"
            + "  `lunes` varchar(255) NOT NULL,\n"
            + "  `martes` varchar(255) NOT NULL,\n"
            + "  `miercoles` varchar(255) NOT NULL,\n"
            + "  `jueves` varchar(255) NOT NULL,\n"
            + "  `viernes` varchar(255) NOT NULL,\n"
            + "  `sabado` varchar(255) NOT NULL,\n"
            + "  `domingo` varchar(255) NOT NULL,\n"
            + "  PRIMARY KEY (`zona`)\n"
            + ") ENGINE=InnoDB DEFAULT CHARSET=big5;\n";
    String creaTablaPatron = "DROP TABLE IF EXISTS `patron`;\n"
            + "CREATE TABLE `patron` (\n"
            + "  `zona` int(11) NOT NULL,\n"
            + "  `lunes` varchar(24) NOT NULL,\n"
            + "  `martes` varchar(24) NOT NULL,\n"
            + "  `miercoles` varchar(24) NOT NULL,\n"
            + "  `jueves` varchar(24) NOT NULL,\n"
            + "  `viernes` varchar(24) NOT NULL,\n"
            + "  `sabado` varchar(24) NOT NULL,\n"
            + "  `Domingo` varchar(24) NOT NULL,\n"
            + "  PRIMARY KEY (`zona`)\n"
            + ") ENGINE=InnoDB DEFAULT CHARSET=big5;\n";
    String creaTablaInterseccion = "DROP TABLE IF EXISTS `interseccion`;\n"
            + "CREATE TABLE `interseccion` (\n"
            + "  `zona` int(11) NOT NULL,\n"
            + "  `x` int(11) NOT NULL,\n"
            + "  `y` int(11) NOT NULL,\n"
            + "  PRIMARY KEY (`zona`,`x`,`y`)\n"
            + ") ENGINE=InnoDB DEFAULT CHARSET=big5;\n";
    String creaTablaLimites = "DROP TABLE IF EXISTS `limites`;\n"
            + "CREATE TABLE `limites` (\n"
            + "  `avenida` int(11) NOT NULL,\n"
            + "  `sentido` varchar(1) NOT NULL,\n"
            + "  `velocidadmaxima` int(11) NOT NULL,\n"
            + "  PRIMARY KEY (`avenida`,`sentido`)\n"
            + ") ENGINE=InnoDB DEFAULT CHARSET=big5;\n";
    String creaTablaUsuario = "DROP TABLE IF EXISTS `usuario`;\n"
            + "CREATE TABLE `usuario` (\n"
            + "  `id` int(11) NOT NULL AUTO_INCREMENT,\n"
            + "  `usuario` varchar(45) DEFAULT NULL,\n"
            + "  `contrasenia` varchar(45) DEFAULT NULL,\n"
            + "  `nombres` varchar(45) DEFAULT NULL,\n"
            + "  `apellidos` varchar(45) DEFAULT NULL,\n"
            + "  `correo` varchar(45) DEFAULT NULL,\n"
            + "  PRIMARY KEY (`id`),\n"
            + "  UNIQUE KEY `usuario_UNIQUE` (`usuario`)\n"
            + ") ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=big5;\n"
            + "INSERT INTO `usuario` VALUES (12,'admin','admin','Juan Carlos','Perez Mendieta','jcperez@gmail.com');\n";
}
